package com.smart.community.commons.interceptor;

import java.util.concurrent.atomic.AtomicLong;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.smart.community.commons.config.BusinessMetricsRegistrar;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;

/**
 * API性能监控拦截器
 * 功能：
 * 1. 监控API请求响应时间
 * 2. 统计请求成功率
 * 3. 记录请求QPS
 * 4. 监控异常请求
 * 
 * @author Wu.Liang
 * @since 2024-12-20
 */
@Slf4j
@Component
public class PerformanceMonitoringInterceptor implements HandlerInterceptor {

    // 请求开始时间的ThreadLocal存储
    private static final ThreadLocal<Long> REQUEST_START_TIME = new ThreadLocal<>();

    // 性能统计计数器
    private final AtomicLong totalRequests = new AtomicLong(0);
    private final AtomicLong successRequests = new AtomicLong(0);
    private final AtomicLong errorRequests = new AtomicLong(0);

    // Micrometer指标
    private MeterRegistry meterRegistry;
    private Counter totalRequestsCounter;
    private Counter successRequestsCounter;
    private Counter errorRequestsCounter;
    private Timer requestTimer;

    @Autowired
    private BusinessMetricsRegistrar businessMetricsRegistrar;

    /**
     * 请求处理前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 记录请求开始时间
        REQUEST_START_TIME.set(System.currentTimeMillis());
        
        // 记录请求信息（DEBUG级别）
        if (log.isDebugEnabled()) {
            log.debug("📊 API监控 - 请求开始: {} {}", request.getMethod(), request.getRequestURI());
        }
        
        return true;
    }

    /**
     * 请求处理后（正常完成）
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        try {
            Long startTime = REQUEST_START_TIME.get();
            if (startTime == null) {
                return;
            }

            // 计算请求处理时间
            long duration = System.currentTimeMillis() - startTime;
            
            // 判断请求是否成功
            boolean isSuccess = (response.getStatus() >= 200 && response.getStatus() < 400) && ex == null;
            
            // 更新统计
            totalRequests.incrementAndGet();
            if (isSuccess) {
                successRequests.incrementAndGet();
            } else {
                errorRequests.incrementAndGet();
            }
            
            // 记录详细的性能指标
            recordDetailedMetrics(request, response, duration, isSuccess, ex);
            
            // 慢请求告警
            if (duration > 5000) { // 超过5秒的请求
                log.warn("🚨 慢请求告警: {} {} - 耗时:{}ms",
                    request.getMethod(), request.getRequestURI(), duration);
            }
            
        } catch (Exception e) {
            log.error("API性能监控处理异常", e);
        } finally {
            // 清理ThreadLocal
            REQUEST_START_TIME.remove();
        }
    }

    /**
     * 记录详细的性能指标
     */
    private void recordDetailedMetrics(HttpServletRequest request, HttpServletResponse response,
                                     long duration, boolean isSuccess, Exception ex) {
        try {
            // 初始化指标（延迟初始化）
            initializeMetrics();
            
            if (meterRegistry != null) {
                // 记录请求处理时间
                if (requestTimer != null) {
                    requestTimer.record(duration, java.util.concurrent.TimeUnit.MILLISECONDS);
                }
                
                // 按状态码统计
                if (totalRequestsCounter != null) {
                    totalRequestsCounter.increment();
                }
                
                if (isSuccess) {
                    if (successRequestsCounter != null) {
                        successRequestsCounter.increment();
                    }
                } else {
                    if (errorRequestsCounter != null) {
                        errorRequestsCounter.increment();
                    }
                }
                
                // 按HTTP方法统计
                Counter.builder("api.requests.by_method")
                    .tag("method", request.getMethod())
                    .description("按HTTP方法统计的请求数")
                    .register(meterRegistry)
                    .increment();
                
                // 按状态码统计
                Counter.builder("api.requests.by_status")
                    .tag("status", String.valueOf(response.getStatus()))
                    .description("按状态码统计的请求数")
                    .register(meterRegistry)
                    .increment();
                
                // 按URI统计（简化版）
                String uri = getSimplifiedURI(request.getRequestURI());
                Timer.builder("api.requests.by_uri")
                    .tag("uri", uri)
                    .description("按URI统计的请求时间")
                    .register(meterRegistry)
                    .record(duration, java.util.concurrent.TimeUnit.MILLISECONDS);
                
                // 异常统计
                if (ex != null) {
                    Counter.builder("api.requests.exceptions")
                        .tag("exception", ex.getClass().getSimpleName())
                        .description("API请求异常统计")
                        .register(meterRegistry)
                        .increment();
                }
            }
            
            // 记录到业务指标注册器
            if (businessMetricsRegistrar != null) {
                businessMetricsRegistrar.recordRequest(isSuccess, duration);
            }
            
            // 输出监控日志
            if (log.isDebugEnabled()) {
                log.debug("📊 API监控 - 请求完成: {} {} - 状态:{} 耗时:{}ms 成功:{}",
                    request.getMethod(), request.getRequestURI(),
                    response.getStatus(), duration, isSuccess);
            }
            
        } catch (Exception e) {
            log.error("记录详细性能指标失败", e);
        }
    }

    /**
     * 初始化Micrometer指标
     */
    private void initializeMetrics() {
        if (meterRegistry != null && totalRequestsCounter == null) {
            totalRequestsCounter = Counter.builder("api.requests.total")
                .description("API总请求数")
                .register(meterRegistry);
            
            successRequestsCounter = Counter.builder("api.requests.success")
                .description("API成功请求数")
                .register(meterRegistry);
            
            errorRequestsCounter = Counter.builder("api.requests.error")
                .description("API错误请求数")
                .register(meterRegistry);
            
            requestTimer = Timer.builder("api.requests.duration")
                .description("API请求处理时间")
                .register(meterRegistry);
        }
    }

    /**
     * 简化URI，去除ID等动态参数
     */
    private String getSimplifiedURI(String uri) {
        if (uri == null) {
            return "unknown";
        }
        
        // 去除数字ID参数
        String simplified = uri.replaceAll("/\\d+", "/{id}");
        
        // 限制长度
        if (simplified.length() > 50) {
            simplified = simplified.substring(0, 50) + "...";
        }
        
        return simplified;
    }

    /**
     * 获取当前性能统计
     */
    public PerformanceStats getPerformanceStats() {
        long total = totalRequests.get();
        long success = successRequests.get();
        long error = errorRequests.get();
        
        double successRate = total > 0 ? (double) success / total * 100 : 0;
        double errorRate = total > 0 ? (double) error / total * 100 : 0;
        
        return new PerformanceStats(total, success, error, successRate, errorRate);
    }

    /**
     * 重置性能统计
     */
    public void resetPerformanceStats() {
        totalRequests.set(0);
        successRequests.set(0);
        errorRequests.set(0);
        log.info("📊 API性能统计已重置");
    }

    /**
     * 性能统计数据类
     */
    public static class PerformanceStats {
        private final long totalRequests;
        private final long successRequests;
        private final long errorRequests;
        private final double successRate;
        private final double errorRate;

        public PerformanceStats(long totalRequests, long successRequests, long errorRequests,
                              double successRate, double errorRate) {
            this.totalRequests = totalRequests;
            this.successRequests = successRequests;
            this.errorRequests = errorRequests;
            this.successRate = successRate;
            this.errorRate = errorRate;
        }

        // Getters
        public long getTotalRequests() {
            return totalRequests;
        }

        public long getSuccessRequests() {
            return successRequests;
        }

        public long getErrorRequests() {
            return errorRequests;
        }

        public double getSuccessRate() {
            return successRate;
        }

        public double getErrorRate() {
            return errorRate;
        }

        @Override
        public String toString() {
            return String.format("PerformanceStats{total=%d, success=%d(%.2f%%), error=%d(%.2f%%)}",
                totalRequests, successRequests, successRate, errorRequests, errorRate);
        }
    }
} 